package com.quan.junit.test.generator;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.FileOutConfig;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.PackageConfig;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
import com.baomidou.mybatisplus.generator.config.converts.MySqlTypeConvert;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.DbColumnType;
import com.baomidou.mybatisplus.generator.config.rules.DbType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.quan.common.utils.CommonUtils;

/**
 * MyBatis Plus 代码生成工具类
 * 
 * @author yhaoquan
 *
 */
public class MyBatisGenerator {

	private final static String dbUrl = "jdbc:mysql://localhost:3306/quan_mars_cloud_project?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false";
	private final static String driverClass = "com.mysql.jdbc.Driver";
	private final static String username = "quan";
	private final static String password = "orange";

	// 输出目录（当前项目的根路径）
	private final static String OUTPUTDIR = System.getProperty("user.dir") + "/generate";

	// 页面输出目录
	private final static String VIEW_VUE_OUTPUTDIR = OUTPUTDIR + "/view/vue";
	
	// API JS文件目录
	private final static String VUE_API_JS_OUTPUTDIR = OUTPUTDIR + "/view/js";

	
	public static void main(String[] args) {
		generateSystem();
		//generateMall();
	}
	
	/**
	 * 电商
	 */
	public static void generateMall() {
		
		List<String> tables = new ArrayList<String>();
		tables.add("tb_mall_goods_brand");
		tables.add("tb_mall_goods_category");
		tables.add("tb_mall_goods_type");
		tables.add("tb_mall_goods_sku");
		tables.add("tb_mall_goods_spec_attr");
		tables.add("tb_mall_goods_spec_value");
		tables.add("tb_mall_goods");
		tables.add("tb_mall_goods_spu_spec_attr");
		tables.add("tb_mall_goods_spu_spec_value");
		tables.add("tb_mall_goods_spu_spec_attr_and_value");
		tables.add("tb_mall_goods_images");
		tables.add("tb_mall_goods_tags");
		tables.add("tb_mall_goods_and_tags");
		
		tables.add("tb_mall_freight_company");
		
		tables.add("tb_mall_user");
		tables.add("tb_mall_user_address");
		
		String[] strings = new String[tables.size()];
		MyBatisGenerator.generate("com.quan.mall", "mall", tables.toArray(strings));
	}

	/**
	 * 系统管理
	 */
	public static void generateSystem() {
		
		List<String> tables = new ArrayList<String>();
		tables.add("tb_system_area");
		tables.add("tb_system_user_role");
		tables.add("tb_system_user");
		tables.add("tb_system_role_permission");
		tables.add("tb_system_role");
		tables.add("tb_system_permission");
		tables.add("tb_system_oss_config");
		tables.add("tb_system_oss");
		tables.add("tb_system_menu");
		tables.add("tb_system_log");
		
		String[] strings = new String[tables.size()];
		MyBatisGenerator.generate("com.quan.system", "system", tables.toArray(strings));
	}

	public static void generate(String packageName, String folder, String... tableNames) {
		AutoGenerator autoGenerator = new AutoGenerator();

		// 数据源配置
		DataSourceConfig dataSourceConfig = new DataSourceConfig();
		dataSourceConfig.setDbType(DbType.MYSQL);
		dataSourceConfig.setUrl(dbUrl);
		dataSourceConfig.setUsername(username);
		dataSourceConfig.setPassword(password);
		dataSourceConfig.setDriverName(driverClass);
		dataSourceConfig.setTypeConvert(new MySqlTypeConvert() {
			@Override
			public DbColumnType processTypeConvert(String fieldType) {
				if ("tinyint(1)".equals(fieldType)) { // 将tinyint转换为boolean类型
					System.out.println("将数据库中的"+fieldType+"转换为Boolean类型");
					return DbColumnType.BOOLEAN;
				}
				// 注意！！processTypeConvert 存在默认类型转换，如果不是你要的效果请自定义返回、非如下直接返回。
				return super.processTypeConvert(fieldType);
			}
		});
		autoGenerator.setDataSource(dataSourceConfig);

		// 全局配置
		GlobalConfig config = new GlobalConfig();
		config.setOutputDir(OUTPUTDIR);
		config.setActiveRecord(true);
		config.setFileOverride(true);
		// XML 二级缓存
		config.setEnableCache(false);
		// XML ResultMap
		config.setBaseResultMap(true);
		// XML columList
		config.setBaseColumnList(true);
		config.setServiceName("%sService");
		config.setAuthor("杨浩泉");
		autoGenerator.setGlobalConfig(config);

		// 策略配置
		StrategyConfig strategyConfig = new StrategyConfig();
		strategyConfig.setTablePrefix("tb_");
		strategyConfig.setSuperControllerClass("com.quan.common.biz.support.BaseController");
		strategyConfig.setSuperMapperClass("com.quan.common.biz.support.BaseMapper");
		strategyConfig.setSuperServiceClass("com.quan.common.biz.support.IBaseService");
		strategyConfig.setSuperServiceImplClass("com.quan.common.biz.support.BaseService");
		// 表名生成策略
		strategyConfig.setNaming(NamingStrategy.underline_to_camel);
		// 修改替换成你需要的表名，多个表名传数组
		if (null != tableNames) {
			strategyConfig.setInclude(tableNames);
		}
		autoGenerator.setStrategy(strategyConfig);

		// 包配置
		PackageConfig packageConfig = new PackageConfig();
		packageConfig.setParent(packageName);
		packageConfig.setController("web.controller");
		autoGenerator.setPackageInfo(packageConfig);

		// 注入自定义配置，可以在 VM 中使用 cfg.abc 设置的值
		InjectionConfig cfg = new InjectionConfig() {
			@Override
			public void initMap() {
			}
		};
		// 生成的模版路径，不存在时需要先新建
		File viewDir = new File(VIEW_VUE_OUTPUTDIR);
		if (!viewDir.exists()) {
			viewDir.mkdirs();
		}

		// Vue 模板
		List<FileOutConfig> focList = new ArrayList<FileOutConfig>();
		focList.add(new FileOutConfig("/templates/view.list.vue.vm") {
			@Override
			public String outputFile(TableInfo tableInfo) {
				return getGeneratorViewPath(VIEW_VUE_OUTPUTDIR, tableInfo, ".vue");
			}
		});

		// API JS 模板
		focList.add(new FileOutConfig("/templates/view.api.js.vm") {
			@Override
			public String outputFile(TableInfo tableInfo) {
				return getGeneratorApiJsPath(VUE_API_JS_OUTPUTDIR, tableInfo, ".js", folder);
			}
		});

		cfg.setFileOutConfigList(focList);
		autoGenerator.setCfg(cfg);

		// 生成
		autoGenerator.execute();
	}

	/**
	 * Vue 页面生成的文件名
	 * @param viewOutputDir
	 * @param tableInfo
	 * @param suffixPath
	 * @return
	 */
	private static String getGeneratorViewPath(String viewOutputDir, TableInfo tableInfo, String suffixPath) {
		String deNamePath = CommonUtils.replaceUnderlineAndfirstToUpper(CommonUtils.upperCharToUnderLine(tableInfo.getEntityName()), "_", "\\") ;
		
		String path = viewOutputDir + "/" + deNamePath + "/index" + suffixPath;
		File viewDir = new File(path).getParentFile();
		if (!viewDir.exists()) {
			viewDir.mkdirs();
		}
		return path;
	}

	/**
	 * API JS生成文件名
	 * @param viewOutputDir
	 * @param tableInfo
	 * @param suffixPath
	 * @param folder 目录
	 * @return
	 */
	private static String getGeneratorApiJsPath(String viewOutputDir, TableInfo tableInfo, String suffixPath, String folder) {
		String name = tableInfo.getEntityName().replaceAll("Mall", "");
		
		String path = viewOutputDir + "/"+folder+"/" + name + suffixPath;
		File viewDir = new File(path).getParentFile();
		if (!viewDir.exists()) {
			viewDir.mkdirs();
		}
		return path;
	}

}
